package com.ddstation.onsitelaw.controller;

import com.ddstation.onsitelaw.model.auditmodel.UserModel;
import com.ddstation.onsitelaw.service.TokenService;
import com.ddstation.onsitelaw.service.Wx3thPlatformServiceItf;
import com.ddstation.onsitelaw.utils.Constant;
import com.ddstation.onsitelaw.utils.ServiceResult;
import com.ddstation.security.util.WnUserIdCrypt;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.taobao.api.ApiException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.inject.Inject;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;


/**
 * 微应用QuickStart示例，免登功能
 *
 * @author openapi@dingtalk
 * @date 2020/2/4
 */
@Controller
public class DingTalkController {
    private static final Logger log = LoggerFactory.getLogger(DingTalkController.class);
    @Inject
    private TokenService tokenService;
    @Inject
    private Wx3thPlatformServiceItf wx3thPlatformServiceItf;

    @Autowired
    public DingTalkController(
            TokenService tokenService
    ) {
        this.tokenService = tokenService;
    }

    /**
     *
     */
    @RequestMapping("dingTalkAuthority")
    String dingTalkAuthority(Model model, @RequestParam("corpId") String corpId) {
        model.addAttribute("corpId", corpId);
        return "app/dingTalkAuthority";
    }

    /**
     * 钉钉用户登录，显示当前登录用户的userId和名称
     *
     * @param authCode 免登临时authCode
     * @return 当前用户
     */
    @RequestMapping(value = "getDingTalkUserInfo", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getDingTalkUserInfo(@RequestParam String authCode, HttpSession session) {
        String accessToken;
        Map<String, Object> map = new HashMap<>();
        map.put("errCode", 0);
        map.put("errMsg", "服务器繁忙，请稍后再试。");

        // 获取accessToken
        ServiceResult<String> accessTokenSr = tokenService.getAccessToken();
        if (!accessTokenSr.isSuccess()) {
        }
        accessToken = accessTokenSr.getResult();

        // 获取用户userId
        ServiceResult<String> userIdSr = getUserInfo(accessToken, authCode);
        if (!userIdSr.isSuccess()) {
        }

        // 获取用户详情
        ServiceResult<UserModel> user = getUser(accessToken, userIdSr.getResult());
        UserModel userModel = user.getResult();

        int uid = wx3thPlatformServiceItf.selectWxUser(userModel);
        if (uid == -1) {
            userModel.setTypeSource(2);
            uid = wx3thPlatformServiceItf.insertWxUserUUID(userModel);
        }
        String encryptUid = WnUserIdCrypt.encrypt(uid, 0);
        session.setAttribute("encryptUid", encryptUid);
        map.put("errCode", 1);
        map.put("errMsg", "请求成功");
        return map;
    }

    /**
     * 访问/user/getuserinfo接口获取用户userId
     *
     * @param accessToken access_token
     * @param authCode    临时授权码
     * @return 用户userId或错误信息
     */
    private ServiceResult<String> getUserInfo(String accessToken, String authCode) {
        DingTalkClient client = new DefaultDingTalkClient(Constant.URL_GET_USER_INFO);
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(authCode);
        request.setHttpMethod("GET");

        OapiUserGetuserinfoResponse response;
        try {
            response = client.execute(request, accessToken);
        } catch (ApiException e) {
            log.error("Failed to {}", Constant.URL_GET_USER_INFO, e);
            return ServiceResult.failure(e.getErrCode(), "Failed to getUserInfo: " + e.getErrMsg());
        }
        if (!response.isSuccess()) {
            return ServiceResult.failure(response.getErrorCode(), response.getErrmsg());
        }

        return ServiceResult.success(response.getUserid());
    }

    /**
     * 访问/user/get 获取用户名称
     *
     * @param accessToken access_token
     * @param userId      用户userId
     * @return 用户名称或错误信息
     */
    private ServiceResult<UserModel> getUser(String accessToken, String userId) {
        DingTalkClient client = new DefaultDingTalkClient(Constant.URL_USER_GET);
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(userId);
        request.setHttpMethod("GET");

        OapiUserGetResponse response;
        try {
            response = client.execute(request, accessToken);
        } catch (ApiException e) {
            log.error("Failed to {}", Constant.URL_USER_GET, e);
            return ServiceResult.failure(e.getErrCode(), "Failed to getUserName: " + e.getErrMsg());
        }

        UserModel user = new UserModel();
        user.setName(response.getName());
        user.setUserId(response.getUserid());
        user.setAvatar(response.getAvatar());
        user.setOpen_userid(response.getOpenId());
        return ServiceResult.success(user);
    }
}
